#define _BSD_SOURCE  // strdup()

#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <string.h>

#include "node.h"

//TODO setitimer() to do shutdown after a certain amount of time

void main_help();
void main_parse();

int main(int argc, char *argv[])
{
	/* A string listing valid short options letters */
	const char *short_options = "s:d:l:u:j:hv:"; // 
	/* An array describing valid long options */
	const struct option long_options[] = {
		{"srv", 1, NULL, 's'},
		{"dir", 1, NULL, 'd'},
		{"listen", 1, NULL, 'l'},
		{"ui", 1, NULL, 'u'},
		{"join", 1, NULL, 'j'},
		{"help", 0, NULL, 'h'},
		{"verbose", 1, NULL, 'v'},
		{NULL, 0, NULL, 0} // name, has_arg, flag, val
	};

	Node *node = NULL;
	if((node = (Node *)malloc(sizeof(Node))) == NULL) {
		perror("malloc");
		fprintf(stderr, "Fatal error\n");
		exit(0);
	}
	memset(node, 0, sizeof(Node));

	/* Parse command line arguments */
	int next_option; // return value from getopt_long
	Addr *join = NULL;

	do {
		next_option = getopt_long(argc, argv, short_options, long_options, NULL);
		switch(next_option) {
		case 's':
			node->srv_name = optarg;
			break;
		case 'd':
			node->dir_name = optarg;
			break;
		case 'l':
			if(!(node->addr = addr_set_str(NULL, optarg)))
				fprintf(stderr, "Invalid listening P2P address. Using default.\n");
			break;
		case 'u':
			sscanf(optarg, "%d", &node->port_ui);
			break;
		case 'j':
			if(!(join = addr_set_str(NULL, optarg)))
				fprintf(stderr, "Invalid P2P address for entry point. Not joining.\n");
			break;
		case 'h':
			main_help();
			exit(0); // we don't have to free()
			break;
		case 'v':
			sscanf(optarg, "%d", &node->verbosity);
			break;
		}
	} while(next_option != -1);

	/* Use default values if argument not supplied */
	if(!node->srv_name)
		node->srv_name = strdup("prsp2p-mabisch-mmoraru");
	if(!node->dir_name)
		node->dir_name = strdup("/tmp/prsp2p-mabisch-mmoraru");
	if(!node->addr)
		node->addr = addr_set(NULL, "127.0.0.1", 30002, 30003);
	node->addr_left = addr_dup(node->addr);
	node->addr_right = addr_dup(node->addr);
	if(node->port_ui <= 0)
		node->port_ui = 30001;
	if(node->verbosity < 0)
		node->verbosity = 0;
	node->req_id = -1; // I know it's an uint
	node->search = search_new();

	/* Node initialization */
	node_init(node, join);
	addr_delete(&join);

	/* Enter main loop */
	node_loop(node);

	/* Shutdown */
	node_shutdown(node, 0); // never reached

	return 0;
}

void main_help()
{
	FILE *stream = stdout;
	fprintf(stream, "Usage: node [options]\n");
	fprintf(stream,
		"  -s, --srv=NAME    Server name\n"
		"  -d, --dir=DIR     Directory for download files\n"
		"  -l, --listen=ADDR Listening P2P address\n"
		"  -u, --ui=PORT     Listening UI port\n"
		"  -j, --join=ADDR   Connect to node with P2P address ADDR after init.\n"
		"  -h, --help        Display this message\n"
		"  -v, --verbose=INT Debug verbosity level:\n"
		"                    0 - print nothing\n"
		"                    0 - print nothing\n"
		"                    0 - print nothing\n"
		"  ADDR has the format ip:tcp_port:udp_port\n"
	);
}

/*
void main_parse()
{
	node->verbosity = 16;
	node->srv_name = "prsp2p";
	node->dir_name = "/tmp/prsp2p";
	node->addr = addr_set(NULL, "127.0.0.1", 30002, 30003);
	node->addr_left = addr_set(NULL, "127.0.0.1", 30002, 30003);
	node->addr_right = addr_set(NULL, "127.0.0.1", 30002, 30003);
	node->port_ui = 30001;
	node->req_id = -1; // I know it's an uint
	node->search = search_new();
}
*/
